package org.jeecg.modules.miniprogram;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import me.chanjar.weixin.common.error.WxErrorException;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.config.init.WxMaConfiguration;
import org.jeecg.modules.customer.entity.BusCustomer;
import org.jeecg.modules.customer.service.IBusCustomerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 微信小程序用户接口
 *
 * @author <a href="https://github.com/binarywang">Binary Wang</a>
 */
@RestController
@RequestMapping("/wx/user/{appid}")
public class WxMaUserController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private IBusCustomerService customerService;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 登陆接口
     */
    @GetMapping("/login")
    public Result login(@PathVariable String appid, @RequestParam("code") String code) {
        try {
            JSONObject result = new JSONObject();
            final WxMaService wxService = WxMaConfiguration.getMaService(appid);

            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
            BusCustomer one = customerService.getOne(new QueryWrapper<BusCustomer>().eq("open_id", session.getOpenid()));
            if (null != one) {
                String token = saveToken(one.getSysUserId());
                result.put("token", token);
                result.put("type", "user");
                result.put("data", one);
            } else {
                result.put("type", "code");
                result.put("data", session);
            }
            return Result.OK(result);
        } catch (WxErrorException e) {
            this.logger.error(e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    private String saveToken(String userId) {
        String token = JwtUtil.signMini(userId);
        redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
        // 设置超时时间
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 1000);
        return token;
    }

    /**
     * <pre>
     * 获取用户信息接口
     * </pre>
     */
    @GetMapping("/info")
    public Result info(@PathVariable String appid, String sessionKey,
                       String signature, String rawData, String encryptedData, String iv) {
        final WxMaService wxService = WxMaConfiguration.getMaService(appid);
        // 用户信息校验
        if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            return Result.error("user check failed");
        }
        // 解密用户信息
        WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
        return Result.OK(userInfo);
    }

    /**
     * <pre>
     * 获取用户绑定手机号信息
     * </pre>
     */
    @GetMapping("/phone")
    public Result phone(@PathVariable String appid, String sessionKey, String signature,
                        String rawData, String encryptedData, String iv) {
        final WxMaService wxService = WxMaConfiguration.getMaService(appid);
        // 用户信息校验
        if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            return Result.error("user check failed");
        }
        // 解密
        WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
        return Result.OK(phoneNoInfo);
    }

}
